gdk: Add gdk_gl_context_is_shared()
authorBenjamin Otte <otte@redhat.com>
Wed, 30 Jun 2021 02:52:35 +0000 (04:52 +0200)
committerBenjamin Otte <otte@redhat.com>
Thu, 22 Jul 2021 14:27:31 +0000 (16:27 +0200)
... and use it in the GL renderers.

gdk/gdkglcontext.c
gdk/gdkglcontext.h
gdk/gdkglcontextprivate.h
gsk/gl/gskgldriver.c
gsk/ngl/gskngldriver.c

index a82c7e3bc4c756900e7550b7a45c74354eede48a..6681b446484ca42fb2dea83ba4bc488160ef6b12 100644 (file)
@@ -333,6 +333,18 @@ gdk_gl_context_real_get_damage (GdkGLContext *context)
                                         });
 }
 
+static gboolean
+gdk_gl_context_real_is_shared (GdkGLContext *self,
+                               GdkGLContext *other)
+{
+  if (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self)) != gdk_draw_context_get_display (GDK_DRAW_CONTEXT (other)))
+    return FALSE;
+
+  /* XXX: Should we check es or legacy here? */
+
+  return TRUE;
+}
+
 static void
 gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
                                  cairo_region_t *region)
@@ -406,6 +418,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
 
   klass->realize = gdk_gl_context_real_realize;
   klass->get_damage = gdk_gl_context_real_get_damage;
+  klass->is_shared = gdk_gl_context_real_is_shared;
 
   draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
   draw_context_class->end_frame = gdk_gl_context_real_end_frame;
@@ -812,6 +825,42 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
   priv->is_legacy = !!is_legacy;
 }
 
+/**
+ * gdk_gl_context_is_shared:
+ * @self: a `GdkGLContext`
+ * @other: the `GdkGLContext` that should be compatible with @self
+ *
+ * Checks if the two GL contexts can share resources.
+ *
+ * When they can, the texture IDs from @other can be used in @self. This
+ * is particularly useful when passing `GdkGLTexture` objects between
+ * different contexts.
+ *
+ * Contexts created for the same display with the same properties will
+ * always be compatible, even if they are created for different surfaces.
+ * For other contexts it depends on the GL backend.
+ *
+ * Both contexts must be realized for this check to succeed. If either one
+ * is not, this function will return %FALSE.
+ *
+ * Returns: %TRUE if the two GL contexts are compatible.
+ */
+gboolean
+gdk_gl_context_is_shared (GdkGLContext *self,
+                          GdkGLContext *other)
+{
+  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
+  GdkGLContextPrivate *priv_other = gdk_gl_context_get_instance_private (other);
+
+  g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
+  g_return_val_if_fail (GDK_IS_GL_CONTEXT (other), FALSE);
+
+  if (!priv->realized || !priv_other->realized)
+    return FALSE;
+
+  return GDK_GL_CONTEXT_GET_CLASS (self)->is_shared (self, other);
+}
+
 /**
  * gdk_gl_context_set_use_es:
  * @context: a `GdkGLContext`
index 10bac82e9bfa0ac0373d19d413c80232c968adc4..278da869ca14cd3eb26c7dd4c3e5e7a5fb3869de 100644 (file)
@@ -54,6 +54,9 @@ void                    gdk_gl_context_get_version              (GdkGLContext  *
                                                                  int           *minor);
 GDK_AVAILABLE_IN_ALL
 gboolean                gdk_gl_context_is_legacy                (GdkGLContext  *context);
+GDK_AVAILABLE_IN_4_4
+gboolean                gdk_gl_context_is_shared                (GdkGLContext  *self,
+                                                                 GdkGLContext  *other);
 
 GDK_AVAILABLE_IN_ALL
 void                    gdk_gl_context_set_required_version     (GdkGLContext  *context,
index 2f9fc23eed6f17f2be0ba56889cba7e7b94da6b0..b64a6f451015beabfde427305555924f78e4b461 100644 (file)
@@ -52,10 +52,13 @@ struct _GdkGLContextClass
 {
   GdkDrawContextClass parent_class;
 
-  gboolean (* realize) (GdkGLContext *context,
-                        GError **error);
+  gboolean              (* realize)                             (GdkGLContext          *context,
+                                                                 GError               **error);
 
-  cairo_region_t * (* get_damage) (GdkGLContext *context);
+  cairo_region_t *      (* get_damage)                          (GdkGLContext          *context);
+
+  gboolean              (* is_shared)                           (GdkGLContext          *self,
+                                                                 GdkGLContext          *other);
 };
 
 typedef struct {
index 621c25825c34905e57703536cfd9509d5091d8e0..8fe726b31515d5d50aceb10cea4deaf375141151 100644 (file)
@@ -518,14 +518,13 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
 
   if (GDK_IS_GL_TEXTURE (texture))
     {
-      GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture);
-      GdkGLContext *shared_context = gdk_gl_context_get_shared_context (self->gl_context);
+      GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
+      GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
 
-      if (texture_context == self->gl_context ||
-          (gdk_gl_context_get_shared_context (texture_context) == shared_context && shared_context != NULL))
+      if (gdk_gl_context_is_shared (self->gl_context, texture_context))
         {
           /* A GL texture from the same GL context is a simple task... */
-          return gdk_gl_texture_get_id ((GdkGLTexture *)texture);
+          return gdk_gl_texture_get_id (gl_texture);
         }
       else
         {
index 32862047d8d9b7beea4ae526e8ddc810229d3b17..eba888f5144b7eb797b8b7bc7ba666f1734360f8 100644 (file)
@@ -741,16 +741,13 @@ gsk_ngl_driver_load_texture (GskNglDriver *self,
 
   if (GDK_IS_GL_TEXTURE (texture))
     {
-      GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture);
-      GdkGLContext *shared_context = gdk_gl_context_get_shared_context (context);
-
-      if (texture_context == context ||
-          (shared_context != NULL &&
-           shared_context == gdk_gl_context_get_shared_context (texture_context)))
+      GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
+      GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
 
+      if (gdk_gl_context_is_shared (context, texture_context))
         {
           /* A GL texture from the same GL context is a simple task... */
-          return gdk_gl_texture_get_id ((GdkGLTexture *)texture);
+          return gdk_gl_texture_get_id (gl_texture);
         }
       else
         {